/*
RSA算法是使用整数进行加密运算的，
在RSA公钥中包含了两个信息：公钥对应的整数e和用于取模的整数n。
对于明文数字m，计算密文的公式是：me mod n。因此，编程步骤如下：
（1） 获取公钥

      FileInputStream f=new FileInputStream("Skey_RSA_pub.dat");
      ObjectInputStream b=new ObjectInputStream(f);
      RSAPublicKey  pbk=(RSAPublicKey)b.readObject( );
分析： 从公钥文件Skey_RSA_pub.dat中读取公钥，由于生成使用的是RSA算法，因此从文件读取公钥对象后强制转换为RSAPublicKey类型，以便后面读取RSA算法所需要的参数。

（2） 获取公钥的参数(e, n)
BigInteger e=pbk.getPublicExponent();
BigInteger n=pbk.getModulus();
分析：

（3） 获取明文整数(m)
String s="Hello World!";
byte ptext[]=s.getBytes("UTF8");
BigInteger m=new BigInteger(ptext);

分析：明文是一个字符串，为了用整数表达这个字符串，先使用字符串的getBytes( )方法将其转换为byte类型数组，它其实是字符串中各个字符的二进制表达方式，这一串二进制数转换为一个整数将非常大，因此仍旧使用BigInteger类将这个二进制串转换为整型。
本实例中出于简化，将整个字符串转换为一个整数。实际使用中，应该对明文进行分组，因为RSA算法要求整型数m的值必须小于n。

（4） 执行计算
BigInteger c=m.modPow(e,n);
分析：计算前面的公式：me mod n。方法返回的结果即公式me mod n的计算结果，即密文。
 */
import java.security.*;
import java.security.spec.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import javax.crypto.interfaces.*;
import java.security.interfaces.*;
import java.math.*;
import java.io.*;
public class Enc_RSA{
    public static void main(String args[]) throws Exception{
        String s="Hello World!";
        // 获取公钥及参数e,n
        FileInputStream f=new FileInputStream("Skey_RSA_pub.dat");
        ObjectInputStream b=new ObjectInputStream(f);
        RSAPublicKey  pbk=(RSAPublicKey)b.readObject( );
        //使用RSAPublicKey类的getPublicExponent( )和getModulus( )方法可以分别获得公始中e和n的值。
        // 由于密钥很长，因此对应的整数值非常大，无法使用一般的整型来存储，Java中定义了BigInteger类来存储这类很大的整数并可进行各种运算。
        BigInteger e=pbk.getPublicExponent();
        BigInteger n=pbk.getModulus();
        System.out.println("e= "+e);
        System.out.println("n= "+n);
        // 明文 m
        byte ptext[]=s.getBytes("UTF8");
        BigInteger m=new BigInteger(ptext);
        // 计算密文c,打印
        // BigInteger类中已经提供了方法modPow( )来执行这个计算。底数m执行这个方法，方法modPow( )的第一个参数即指数e，第二个参数即模n。
        BigInteger c=m.modPow(e,n);
        System.out.println("c= "+c);
        // 保存密文
        String cs=c.toString( );
        BufferedWriter out=
                new BufferedWriter(new OutputStreamWriter(
                        new FileOutputStream("Enc_RSA.dat")));
        out.write(cs,0,cs.length( ));
        out.close( );

    }
}